﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Data;

namespace PolePosition.v3.Common
{
    public class BindingLists
    {
        public static BindingList<ListItem> GetList(System.Collections.IList items, string textProperty, string valueProperty, bool addNullItem)
        {
            return GetList(items, textProperty, valueProperty, addNullItem, false);
        }

        public static BindingList<ListItem> GetList(System.Collections.IList items, string textProperty, string valueProperty, bool addNullItem, bool distinct)
        {
            BindingList<ListItem> _Values = new BindingList<ListItem>();
            if (addNullItem)
                _Values.Add(new ListItem());

            System.Reflection.PropertyInfo _TextProperty;
            System.Reflection.PropertyInfo _ValueProperty;

            List<string> _DistinctList;
            _DistinctList = new List<string>();

            if (items == null)
                return _Values;

            foreach (object _item in items)
            {
                string _TextString = null;

                if (!string.IsNullOrEmpty(textProperty))
                {
                    _TextProperty = _item.GetType().GetProperty(textProperty);
                    if (_TextProperty == null)
                        return null;

                    object _Value;
                    _Value = _TextProperty.GetValue(_item, null);

                    if (_Value == null)
                        _TextString = string.Empty;
                    else
                        _TextString = _Value.ToString();
                }

                string _ValueString = null;
                int? _ValueInt = null;

                bool _isValueInt;
                _isValueInt = false;

                if (!string.IsNullOrEmpty(valueProperty))
                {
                    _ValueProperty = _item.GetType().GetProperty(valueProperty);
                    if (_ValueProperty == null)
                        return null;

                    object _Value;
                    _Value = _ValueProperty.GetValue(_item, null);

                    if (_Value == null)
                        _ValueString = string.Empty;
                    else
                        _ValueString = _Value.ToString();

                    // do an int parse to see if value is a string 
                    // or an int so that databinding works appropriately

                    int _ParseValue;
                    if (int.TryParse(_ValueString, out _ParseValue))
                    {
                        _ValueInt = _ParseValue;
                        _isValueInt = true;
                    }
                }

                // handle distinct

                if (distinct)
                {
                    string _DistinctString;
                    _DistinctString = string.Concat(_TextString, _ValueString);

                    if (_DistinctString == string.Empty || _DistinctList.Contains(_DistinctString))
                        continue;
                    else
                        _DistinctList.Add(_DistinctString);
                }

                //use correct value to populate list item

                if (_isValueInt)
                    _Values.Add(new ListItem() { Text = _TextString, Value = _ValueInt, Tag = _item });
                else
                    _Values.Add(new ListItem() { Text = _TextString, Value = _ValueString, Tag = _item });
            }

            OrderBindingListByText(true, _Values);

            return _Values;
        }

        public static BindingList<ListItem> GetList(DataTable items, string textProperty, string valueProperty, bool addNullItem)
        {
            return GetList(items, textProperty, valueProperty, addNullItem, false);
        }

        public static BindingList<ListItem> GetList(DataTable items, string textProperty, string valueProperty, bool addNullItem, bool distinct)
        {
            BindingList<ListItem> _Values = new BindingList<ListItem>();
            if (addNullItem)
                _Values.Add(new ListItem());

            List<string> _DistinctList;
            _DistinctList = new List<string>();

            if (items == null)
                return _Values;

            if (!string.IsNullOrEmpty(textProperty) && !items.Columns.Contains(textProperty))
                ProjectCommon2.Helpers.ExceptionHelper.Throw(new MissingFieldException(textProperty));

            if (!string.IsNullOrEmpty(valueProperty) && !items.Columns.Contains(valueProperty))
                ProjectCommon2.Helpers.ExceptionHelper.Throw(new MissingFieldException(valueProperty));


            foreach (DataRow _item in items.Rows)
            {
                string _TextString = null;

                if (!string.IsNullOrEmpty(textProperty))
                {
                    object _Value;
                    _Value = _item[textProperty];

                    if (_Value == null)
                        _TextString = string.Empty;
                    else
                        _TextString = _Value.ToString();
                }

                string _ValueString = null;
                int? _ValueInt = null;

                bool _isValueInt;
                _isValueInt = false;

                if (!string.IsNullOrEmpty(valueProperty))
                {

                    object _Value;
                    _Value = _item[valueProperty];

                    if (_Value == null)
                        _ValueString = string.Empty;
                    else
                        _ValueString = _Value.ToString();

                    // do an int parse to see if value is a string 
                    // or an int so that databinding works appropriately

                    int _ParseValue;
                    if (int.TryParse(_ValueString, out _ParseValue))
                    {
                        _ValueInt = _ParseValue;
                        _isValueInt = true;
                    }
                }

                // handle distinct
                if (distinct)
                {
                    string _DistinctString;
                    _DistinctString = string.Concat(_TextString, _ValueString);

                    if (_DistinctString == string.Empty || _DistinctList.Contains(_DistinctString))
                        continue;
                    else
                        _DistinctList.Add(_DistinctString);
                }

                //use correct value to populate list item

                if (_isValueInt)
                    _Values.Add(new ListItem() { Text = _TextString, Value = _ValueInt, Tag = _item });
                else
                    _Values.Add(new ListItem() { Text = _TextString, Value = _ValueString, Tag = _item });
            }

            return _Values;
        }

        public static BindingList<ListItem> OrderBindingListByText(bool ascending, BindingList<ListItem> list)
        {
            if (list == null || list.Count() < 1)
                return list;

            if (ascending)
            {
                var _list = from _listitem in list
                            orderby _listitem.Text ascending
                            select _listitem;

                return new BindingList<ListItem>(_list.ToArray());
            }
            else
            {
                var _list = from _listitem in list
                            orderby _listitem.Text descending
                            select _listitem;

                return new BindingList<ListItem>(_list.ToArray());
            }
        }

        public class ListItem
        {
            public string Text { get; set; }
            public object Value { get; set; }
            public object Tag { get; set; }
            /*
            public override string ToString()
            {
                return Text;
            }*/
        }
    }
}
